---
title: Accessibility
redirect_from:
  - /components/seat/accessibility/
---

# Accessibility

## Seat

The Seat component has been designed with accessibility in mind.

It can be used with keyboard navigation, and it includes the following properties that allow to improve the experience for users of assistive technologies:

| Name            | Type     | Description                                                                                                                 |
| :-------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------- |
| aria-labelledby | `string` | Id(s) of elements that announce the component to screen readers.                                                            |
| title           | `string` | Adds the `title` attribute to the rendered SVG element. Announced by screen readers after the `aria-labelledby` element(s). |
| description     | `string` | Adds the `description` attribute to the rendered SVG element. Announced by screen readers after the `title` value.          |

All the props above are optional, but recommended to use to ensure the best experience for all users.

The `aria-labelledby` prop can reference multiple ids, separated by a space.
The elements with those ids can be hidden, so that their text is only announced by screen readers.

The `title` and `description` props are used to provide additional context to the rendered SVG element that visually represents the seat.
They are also announced by screen readers.

The conjugation of these properties allows to provide a detailed description of the seat to users of assistive technologies.

## SeatLegend

The SeatLegend component is not interactive. However, it accepts the `aria-label` prop, that is passed to the rendered SVG element.

It allows for screen readers to provide a meaningful description of the seat type, which can be useful for users of assistive technologies.

The `label` prop is also announced by screen readers.

### Automatic Accessibility Features

- The component automatically manages ARIA attributes:
  - Uses `aria-pressed` to communicate the selection state of the seat
  - Sets `aria-disabled="true"` for unavailable seats
  - Combines `aria-labelledby`, `title`, and `description` for comprehensive screen reader announcements
- Focus management is handled automatically:
  - Seats with `onClick` function are rendered as interactive buttons with proper focus indicators
- State management is handled automatically:
  - Selected state is visually indicated with a highlight
  - Unavailable seats have distinct styling to indicate they cannot be selected

### Best Practices

- Always provide either `title`, `aria-labelledby`, or both to ensure seats have accessible names.
- Include meaningful `description` for seats with special characteristics (like extra legroom).
- Consider adding an explanation of seat types using the SeatLegend component.

### Keyboard Navigation

- **Tab**: Moves focus between interactive (available) seats
- **Space/Enter**: Selects or deselects the focused seat
- Focus order should follow a logical pattern, typically left-to-right and top-to-bottom

### Examples

#### Basic Seat with Accessibility Labels

```jsx
<p id="l1" style={{ display: "none", visibility: "hidden" }}>
  For passenger John Doe
</p>
<Seat
  aria-labelledby="l1"
  title="Seat 1A"
  description="Extra legroom"
  label="25€"
/>
```

It would have the screen reader announce: "For passenger John Doe. Seat 1A. Extra legroom.".

Note that the `label` prop is **not** announced by screen readers, as it is intended for visual representation only.
So be sure to include all relevant information on the three properties that are announced by screen readers.

Alternatively, the paragraph element with the id `l1` is visually hidden, so that its text is only read by screen readers but not present on the screen.

It is also recommended to have those strings translated and change dynamically based on the state of the user journey (eg: if the seat is selected and the user is about to deselect it, the screen reader should announce it).

#### Selected Seat with Price

```jsx
<Seat
  title="Extra legroom seat 1C"
  description="Aisle seat with extra legroom"
  type="legroom"
  selected
  price="€15"
  onClick={() => handleSeatSelection("1C")}
/>
```

Screen reader announces: "Extra legroom seat 1C, Aisle seat with extra legroom, button, pressed".

#### Unavailable Seat

```jsx
<Seat title="Seat 24B already occupied" type="unavailable" />
```

Screen reader announces: "Seat 24B already occupied, dimmed, toggle button".

#### Using External Labels

```jsx
<div>
  <span id="seat-label" className="sr-only">
    Exit row seat 15F
  </span>
  <span id="seat-desc" className="sr-only">
    Extra legroom, additional responsibilities
  </span>
  <Seat
    type="legroom"
    aria-labelledby="seat-label seat-desc"
    onClick={() => handleSeatSelection("15F")}
  />
</div>
```

Mentioned span elements are visually hidden, so that their text is only read by screen readers.

Screen reader announces: "Exit row seat 15F Extra legroom, additional responsibilities, toggle button".

#### Seat Legend with Accessibility Label

```jsx
<div>
  <Seat
    type="legroom"
    title="15F"
    description="Window seat"
    aria-labelledby="legend"
    onClick={() => handleSeatSelection("15F")}
  />{" "}
  <SeatLegend
    id="legend"
    type="legroom"
    label="Extra legroom"
    aria-label="This seat has extra legroom"
  />{" "}
</div>
```

Screen reader announces: "This seat has extra legroom 15F Window seat, toggle button" once the Seat component is focused, and "This seat has extra legroom" once the SeatLegend's legend icon is focused.
